﻿#include "TreeWidget_EditScriptList.h"

#include "qmessagebox.h"
#include "qlist.h"

#include "ScriptInstructionFactory.h"
#include "ScriptRunner.h"
#include "ScriptInstruction.h"


TreeWidget_EditScriptList::TreeWidget_EditScriptList(QWidget* parent):QTreeWidget(parent)
{
	connect(this, &QTreeWidget::itemClicked, this, &TreeWidget_EditScriptList::slot_itemClicked);
}

TreeWidget_EditScriptList::~TreeWidget_EditScriptList()
{
	for (int i=0;i<topLevelItemCount();++i)
	{
		circularDelete(takeTopLevelItem(i));
	}
}

void TreeWidget_EditScriptList::circularDelete(QTreeWidgetItem* parent)
{
	for (int i=0;i<parent->childCount();++i)
	{
		circularDelete(parent->child(i));
	}
	delete parent;
}

bool TreeWidget_EditScriptList::updateScriptList()
{
	QVector<QTreeWidgetItem*> topItemList;
	for (int i = 0; i < topLevelItemCount(); ++i)
	{
		topItemList.append(topLevelItem(i));
	}
	bool isOk = false;
	QVector<QVector<ScriptInstruction*>> scriptList = ScriptInstructionFactory::treeWidgetItemListToScriptList(topItemList, &isOk);
	if (!isOk)
	{
		QMessageBox(QMessageBox::Critical, QStringLiteral("错误"), QStringLiteral("更改当前脚本的过程中，格式转换出错，更改当前脚本失败"));
		return false;
	}
	else
	{
		scriptRunner->setScript(scriptList);
		return true;
	}
}
bool TreeWidget_EditScriptList::showScriptList()
{
	clear();
	QVector<QVector<ScriptInstruction*>> scriptList = scriptRunner->getScript();
	if (scriptList.isEmpty()) //整个代码块都是空的就不用继续解析了
	{
		return  true;
	}
	bool isOk = false;
	QVector<QTreeWidgetItem*> treeWidgetItemList = ScriptInstructionFactory::scriptListToTreeWidgetItemList(scriptList, &isOk);
	if (!isOk)
	{
		QMessageBox::critical(this, QStringLiteral("错误"), QStringLiteral("显示当前脚本的过程中，格式转换出错，显示当前脚本失败"));
		return false;
	}
	else
	{
		addTopLevelItems(QList<QTreeWidgetItem*>::fromVector(treeWidgetItemList));
		return true;
	}
}
void TreeWidget_EditScriptList::itemOperation(ListOperation operationFlag)
{
	QTreeWidgetItem* currentNode = currentItem();//得到当前节点
	if (currentNode == Q_NULLPTR)
	{//当前节点为空代表没有选中节点，直接弹出提醒
		QMessageBox::information(this, QStringLiteral("消息"), QStringLiteral("先选中一个操作"));
		return;
	}
	QTreeWidgetItem* currentParent = currentNode->parent();//当前节点不为空则取其父节点
	if (currentParent != Q_NULLPTR)
	{//若父节点不是空的，则直接在当前父节点下面操作节点
		int index = currentParent->indexOfChild(currentNode);//得到当前节点在父节点的位置
		QTreeWidgetItem* newNode = Q_NULLPTR;
		switch (operationFlag)
		{
		case Clone:
			newNode = currentNode->clone();
			currentParent->insertChild(index + 1, newNode);
			setCurrentItem(newNode);//将操作后的节点设置为当前节点
			break;
		case MoveUp:
			if (index > 0)
			{//若当前节点所在位置在合法范围内，上移一位
				currentParent->takeChild(index);
				currentParent->insertChild(index - 1, currentNode);
				setCurrentItem(currentNode);
			}
			else
			{//若当前节点超出合法范围，弹出提示框
				QMessageBox::information(this, QStringLiteral("消息"), QStringLiteral("无法再上移"));
			}
			break;
		case MoveDown:
			if (index < currentParent->childCount() - 1)
			{//若当前节点所在位置在合法范围内，下移一位
				currentParent->takeChild(index);
				currentParent->insertChild(index + 1, currentNode);
				setCurrentItem(currentNode);
			}
			else
			{//若当前节点超出合法范围，弹出提示框
				QMessageBox::information(this, QStringLiteral("消息"), QStringLiteral("无法再下移"));
			}
			break;
		case Remove:
			delete currentParent->takeChild(index);
			break;
		default:
			QMessageBox::information(this, QStringLiteral("消息"), QStringLiteral("无法识别的操作"));
			break;
		}
		return;
	}
	else
	{//当前节点的父节点为空代表当前节点是顶层节点
		int index = indexOfTopLevelItem(currentNode);//得到当前节点在顶层的位置
		QTreeWidgetItem* newNode = Q_NULLPTR;
		switch (operationFlag)
		{
		case Clone:
			newNode = currentNode->clone();
			insertTopLevelItem(index + 1, newNode);
			setCurrentItem(newNode);//将操作后的节点设置为当前节点
			break;
		case MoveUp:
			if (index > 0)
			{//若当前节点所在位置在合法范围内，上移一位
				takeTopLevelItem(index);
				insertTopLevelItem(index - 1, currentNode);
				setCurrentItem(currentNode);
			}
			else
			{//若当前节点超出合法范围，弹出提示框
				QMessageBox::information(this, QStringLiteral("消息"), QStringLiteral("无法再上移"));
			}
			break;
		case MoveDown:
			if (index < topLevelItemCount() - 1) {//若当前节点所在位置在合法范围内，下移一位
				takeTopLevelItem(index);
				insertTopLevelItem(index + 1, currentNode);
				setCurrentItem(currentNode);
			}
			else {//若当前节点超出合法范围，弹出提示框
				QMessageBox::information(this, QStringLiteral("消息"), QStringLiteral("无法再下移"));
			}
			break;
		case Remove:
			delete takeTopLevelItem(index);//删除节点
			break;
		default:
			QMessageBox::information(this, QStringLiteral("消息"), QStringLiteral("无法识别的操作"));
			break;
		}
		return;
	}
}
void TreeWidget_EditScriptList::slot_itemClicked(QTreeWidgetItem* item, int column)
{
	if (previousItem != item) {
		previousItem = item;
	}
	else {
		setCurrentItem(Q_NULLPTR);
		previousItem = Q_NULLPTR;
	}
}

void TreeWidget_EditScriptList::addOperationNameToList(QString name)
{
	QTreeWidgetItem* newNode = new QTreeWidgetItem();//新建单个脚本节点
	newNode->setText(0, name);//命名新建脚本节点
	QTreeWidgetItem* currentNode = currentItem();//得到当前节点
	if (currentNode == Q_NULLPTR)
	{//当前节点为空代表没有选中节点，直接在最后添加新的节点
		addTopLevelItem(newNode);
	}
	else
	{
		if (ScriptInstructionFactory::getDescribeHead(currentNode->text(0)) == ScriptInstructionFactory::itemText_loop)
		{//如果该节点是一个循环，则为其添加子节点
			currentNode->addChild(newNode);
		}
		else
		{
			QTreeWidgetItem* currentParent = currentNode->parent();//当前节点不为空，且不是循环，则取其父节点
			if (currentParent != Q_NULLPTR)
			{//若父节点不是空的，则直接在当前父节点下面添加新的节点
				int index = currentParent->indexOfChild(currentNode);//得到当前节点在父节点的位置
				currentParent->insertChild(index + 1, newNode);//将新的节点添加到当前位置+1的位置
			}
			else
			{//当前节点的父节点为空代表当前节点是顶层节点
				int index = indexOfTopLevelItem(currentNode);//得到当前节点在顶层的位置
				insertTopLevelItem(index + 1, newNode);//将新节点插入到当前位置+1的位置
			}
		}
	}
	setCurrentItem(newNode);//将新节点设置为当前节点
}

ScriptRunner* TreeWidget_EditScriptList::getScriptRunner()
{
	return scriptRunner;
}
void TreeWidget_EditScriptList::setScriptRunner(ScriptRunner* scriptRunner)
{
	this->scriptRunner = scriptRunner;
}
